/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.ipti.br.tag.bo;

import org.ipti.br.tag.bean.dataManipulation.HumanHbMeasure;
import org.ipti.br.tag.bean.dataManipulation.SelectionElement;
import org.ipti.br.tag.dao.HbFacade;
import org.ipti.br.tag.entity.Campaign;
import org.ipti.br.tag.entity.Hb;
import org.ipti.br.tag.entity.Human;
import org.ipti.br.tag.entity.Organization;
import org.ipti.br.tag.entity.Personage;
import org.ipti.br.tag.entity.Unity;
import org.ipti.br.tag.entity.enums.HBConsentment;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
import javax.inject.Inject;
import org.ipti.br.tag.pdf.ConsentTermListPdf;
import org.ipti.br.tag.pdf.ConsentTermPdf;
import org.ipti.br.tag.pdf.LetterToParentsWarnings;
import org.ipti.br.tag.util.ConsentTermAuxiliator;
import org.ipti.br.tag.util.HbAuxiliator;
import org.ipti.br.tag.util.HbUtil;

/**
 *
 * @author FelipeMSX
 */
@Stateless
public class HbBO {

    @Inject private HbFacade hbFacade;
    @Inject private PersonageBO personageBO;
    @Inject private UnityBO unityBO;
    @Inject private HumanBO humanBO;

    public List<Hb> findAllHb(Unity unity, Campaign campaign) {
        return hbFacade.listAllHb(unity, campaign);
    }

    public Long countHbs(long humanID, long campaignID) {
        return hbFacade.countHbs(humanID, campaignID);
    }

    public List<Human> searchActivatedHuman(Unity unity, Campaign campaign) {
        return hbFacade.searchActivatedHuman(unity, campaign);
    }

    public List<Hb> findAllHbs(Human human, Campaign campaign) {
        return hbFacade.findAllHb(human, campaign);
    }

    public void create(Hb hb) {
        hbFacade.create(hb);
    }

    public void edit(Hb hb) {
        hbFacade.edit(hb);
    }

    public void remove(Hb hb) {
        hbFacade.remove(hb);
    }

    public Hb find(Object id) {
        return hbFacade.find(id);
    }

    public List<Hb> findAll() {
        return hbFacade.findAll();
    }

    public HbFacade getHbFacade() {
        return hbFacade;
    }

    public void setHbFacade(HbFacade hbFacade) {
        this.hbFacade = hbFacade;
    }

    public Hb getLastMeasure(Human human) {
        return hbFacade.getLastMeasure(human);
    }

    public List<Hb> modifiedPerfFreqBetweenDate(Calendar initialDate, Calendar finalDate, Long serialNumber) {
        return getHbFacade().modifiedPerfFreqBetweenDate(initialDate, finalDate, serialNumber);
    }

    public boolean generateConsentTerm(List<Human> humanList, Unity unity) {
        if (humanList.isEmpty()) {
            return false;
        } else {
            try {
                new ConsentTermPdf().run(humanList, unity);
                return true;
            } catch (Exception e) {
                return false;
            }
        }
    }

    public List<SelectionElement<Human, Boolean>> getAuthorizations(Campaign campaign, Unity unity) {
        Organization org = new Organization();
        org.setId(2040438459L);
        List<Unity> unities = unityBO.unityChildrenPerOrganization(unity, org);
        List<SelectionElement<Human, Boolean>> authorizations = new ArrayList<>();

        if (!unities.isEmpty()) {
            for (Unity u : unities) {
                authorizations.addAll(humanBO.getHumanDAO().listAuthorizedStatus(campaign, u));
            }
        } else {
            authorizations.addAll(humanBO.getHumanDAO().listAuthorizedStatus(campaign, unity));
        }
        return authorizations;
    }

    public List<String> saveConsentTerm(List<SelectionElement<Human, Boolean>> consentTermListAuxiliator, Campaign campaign) {
        Hb hb;
        List<String> errors = new ArrayList<>();
        for (SelectionElement<Human, Boolean> element : consentTermListAuxiliator) {
            if (element.isEdited()) {
                hb = getHbFacade().findBy(element.getElement(), campaign, 1);
                if (element.getStatus() == true && hb == null) {
                    hb = new Hb();
                    hb.setCampaign(campaign);
                    hb.setOrdernation((byte) 1);
                    hb.setHemoglobineTax(0f);
                    hb.setAnemic(false);
                    hb.setHuman(element.getElement());
                    this.create(hb);
                } else if (element.getStatus() == false && hb != null && hb.getHemoglobineTax().equals(0f)) {
                    this.remove(hb);
                } else if (element.getStatus() == false && hb != null) {
                    errors.add(element.getElement().getName());
                }
            }
        }
        return errors;
    }

    public boolean printConsentTerm(List<SelectionElement<Human, Boolean>> aceptation,
                                        Campaign campaign, Unity selected, Unity logged) {
        try {
            new ConsentTermListPdf().run(aceptation, logged, selected, campaign);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public List<HumanHbMeasure> getDataTableHB(Unity unity, Campaign campaign) {
        List<HumanHbMeasure> list = new ArrayList<>();
        List<Human> humans = new ArrayList<>();
        
        List<Long> unities = unityBO.unityChildrenPerOrganization2(unity.getId(), 2040438459L);

        if (!unities.isEmpty()) {
            for (Long unityID : unities) {
                humans.addAll(humanBO.getHumanDAO().getActivatedHumans(unityBO.find(unityID)));
            }
        } else {
            humans.addAll(humanBO.getHumanDAO().getActivatedHumans(unity));
        }
        
        HumanHbMeasure hhbm;
        for (Human human : humans) {
            hhbm = new HumanHbMeasure();
            hhbm.setHuman(human);
            hhbm.setHb1(getHbFacade().findBy(human, campaign, 1));
            hhbm.setHb2(getHbFacade().findBy(human, campaign, 2));
            hhbm.setHb3(getHbFacade().findBy(human, campaign, 3));
            if (hhbm.hasHb1()) {
                list.add(hhbm);
            }
        }
        
        return list;
    }

    public void saveHB(List<HumanHbMeasure> HbListAuxiliator, Campaign campaign) {
        for (HumanHbMeasure element : HbListAuxiliator) {
            if (element.hasHb1()) {
                element.getHb1().setAnemic(HbUtil.avaliate(element.getHb1()));
                edit(element.getHb1());
            }
            if (element.hasHb2()) {
                element.getHb2().setAnemic(HbUtil.avaliate(element.getHb2()));
                edit(element.getHb2());
            }
            if (element.hasHb3()) {
                element.getHb3().setAnemic(HbUtil.avaliate(element.getHb3()));
                edit(element.getHb3());
            }
            hbFacade.flush();
        }
    }

    public List<Human> letterToParentsCreateList(Campaign campaign, Unity unity) { //organization and unity tree fix here
        List<Human> humanList = new ArrayList<>();
        Personage personage = personageBO.find((long) 623403461);
        List<Unity> unities = unityBO.unityChildrenPerOrganization(unity, personage.getOrganization()); //extremamente errado

        if (!unities.isEmpty()) {
            for (Unity u : unities) {
                humanList.addAll(humanBO.getHumanDAO().listAnemics(u));
            }
        } else {
            humanList.addAll(humanBO.getHumanDAO().listAnemics(unity));
        }

        return humanList;
    }

    public boolean generateLetterToParendsPdf(List<Human> humanListAnemic, Campaign campaign, Unity selected, Unity logged) {
        if (!humanListAnemic.isEmpty()) {
            try {
                new LetterToParentsWarnings().run(humanListAnemic, logged, selected, campaign);
                return true;
            } catch (Exception e) {
                Logger.getLogger(HbBO.class.getName()).log(Level.SEVERE, null, e);
                return false;
            }
        }
        return false;
    }
    
    public String[] saveConsultation(SelectionElement<Human,Boolean> element, Campaign campaign) {
            if(element.isEdited()) {
                if(element.getStatus()) {
                    if (this.getHbFacade().findBy(element.getElement(), campaign, 2) == null) {
                        this.create(new Hb(0.0f, (byte) 2, campaign, element.getElement()));
                    }
                    if (this.getHbFacade().findBy(element.getElement(), campaign, 3) == null) {
                        this.create(new Hb(0.0f, (byte) 3, campaign, element.getElement()));
                    }
                } else {
                    Hb hb = this.getHbFacade().findBy(element.getElement(), campaign, 2);
                    if (hb != null && hb.getHemoglobineTax() > 0.0f) {
                        String[] msgs = {"Existe um valor atribuito ao HB2",
                            "Edite o HB2 de "+element.getElement().getFirstName()+" para 0"};
                        return msgs;
                    } else if (hb != null) {
                        this.remove(hb);
                    }
                    hb = this.getHbFacade().findBy(element.getElement(), campaign, 3);
                    if (hb != null && hb.getHemoglobineTax() > 0.0f) {
                        String[] msgs = {"Existe um valor atribuito ao HB3",
                            "Edite o HB3 de "+element.getElement().getFirstName()+" para 0"};
                        return msgs;
                    } else if (hb != null) {
                        this.remove(hb);
                    }
                }
            }
        return null;
    }
}
